package cn.psvmc.cxzapi.service.customer;

import cn.psvmc.cxzapi.config.ConfigKey;
import cn.psvmc.cxzapi.exception.ServiceException;
import cn.psvmc.cxzapi.mapper.customer.TCustomerAuthMapper;
import cn.psvmc.cxzapi.mapper.customer.TCustomerCouponMapper;
import cn.psvmc.cxzapi.mapper.customer.TCustomerGoodsRecordMapper;
import cn.psvmc.cxzapi.mapper.customer.TCustomerMapper;
import cn.psvmc.cxzapi.mapper.goods.*;
import cn.psvmc.cxzapi.mapper.market.THotwordMapper;
import cn.psvmc.cxzapi.mapper.market.TSortMapper;
import cn.psvmc.cxzapi.mapper.order.TOrderBillMapper;
import cn.psvmc.cxzapi.mapper.order.TOrderCouponMapper;
import cn.psvmc.cxzapi.mapper.order.TOrderMapper;
import cn.psvmc.cxzapi.mapper.store.TCouponMapper;
import cn.psvmc.cxzapi.mapper.store.TStoreMapper;
import cn.psvmc.cxzapi.mapper.system.TPlatformSetMapper;
import cn.psvmc.cxzapi.mapper.ticket.TTicketCauseMapper;
import cn.psvmc.cxzapi.mapper.ticket.TTicketMapper;
import cn.psvmc.cxzapi.mapper.ticket.TTicketRepliesMapper;
import cn.psvmc.cxzapi.mapper.ticket.TTicketTypeMapper;
import cn.psvmc.cxzapi.model.common.GoodsEntity;
import cn.psvmc.cxzapi.model.common.GoodsSpecsEntity;
import cn.psvmc.cxzapi.model.common.OrderEntity;
import cn.psvmc.cxzapi.model.common.SearchEntity;
import cn.psvmc.cxzapi.model.customer.TCustomer;
import cn.psvmc.cxzapi.model.customer.TCustomerAuth;
import cn.psvmc.cxzapi.model.customer.TCustomerCoupon;
import cn.psvmc.cxzapi.model.goods.*;
import cn.psvmc.cxzapi.model.idcard.Back;
import cn.psvmc.cxzapi.model.idcard.Face;
import cn.psvmc.cxzapi.model.idcard.Warning;
import cn.psvmc.cxzapi.model.market.THotword;
import cn.psvmc.cxzapi.model.order.TOrder;
import cn.psvmc.cxzapi.model.order.TOrderBill;
import cn.psvmc.cxzapi.model.order.TOrderItem;
import cn.psvmc.cxzapi.model.store.TCoupon;
import cn.psvmc.cxzapi.model.ticket.TTicket;
import cn.psvmc.cxzapi.model.ticket.TTicketReplies;
import cn.psvmc.cxzapi.response.Result;
import cn.psvmc.cxzapi.response.ResultGenerator;
import cn.psvmc.cxzapi.service.alipay.AlipayCreate;
import cn.psvmc.cxzapi.service.system.ServiceUtil;
import cn.psvmc.cxzapi.util.CodeUtil;
import cn.psvmc.cxzapi.util.OssService;
import cn.psvmc.cxzapi.util.RecognizeIdcardUtil;
import cn.psvmc.cxzapi.util.ToolUtils;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.response.AlipayFundAuthOrderAppFreezeResponse;
import com.alipay.api.response.AlipayOpenMiniOrderCreateResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.istack.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author ywx
 * @className TCustomerGoodsService
 * @description
 * @date 2024/9/1 18:02
 **/
@Service
@Slf4j
public class TCustomerGoodsService {
    @Resource
    private TSortMapper tSortMapper;
    @Resource
    private TGoodsExampleMapper tGoodsExampleMapper;
    @Resource
    private TCustomerGoodsRecordMapper tCustomerGoodsRecordMapper;
    @Resource
    private TGoodsMapper tGoodsMapper;
    @Resource
    private TGoodsLogisticsMapper goodsLogisticsMapper;
    @Resource
    private TGoodsRentMapper goodsRentMapper;
    @Resource
    private TGoodsAttributeMapper goodsAttributeMapper;
    @Resource
    private TGoodsSpecsMapper goodsSpecsMapper;
    @Resource
    private TGoodsSpecsRentMapper goodsSpecsRentMapper;
    @Resource
    private TCustomerCouponMapper tCustomerCouponMapper;
    @Resource
    private ServiceUtil serviceUtil;
    @Resource
    private TCouponMapper tCouponMapper;
    @Resource
    private TCustomerAuthMapper tCustomerAuthMapper;
    @Resource
    private TTicketTypeMapper tTicketTypeMapper;
    @Resource
    private TTicketCauseMapper tTicketCauseMapper;
    @Resource
    private TTicketMapper tTicketMapper;
    @Resource
    private TTicketRepliesMapper tTicketRepliesMapper;
    @Resource
    private TOrderMapper tOrderMapper;
    @Resource
    private TOrderBillMapper tOrderBillMapper;
    @Resource
    private TOrderCouponMapper tOrderCouponMapper;
    @Resource
    private TGoodsMapper goodsMapper;
    @Resource
    private TPlatformSetMapper platformSetMapper;
    @Resource
    private THotwordMapper tHotwordMapper;
    @Resource
    private TCustomerMapper customerMapper;
    @Resource
    private TStoreMapper storeMapper;

    /**
     * @Description 商品分类列表
     * @Date 2024/9/1 0:01
     * @Author YWX
     * @Param []
     * @Return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     **/
    public List<Map<String, Object>> listGoodsSort() {
        List<Map<String, Object>> list = tSortMapper.listForSel();
        return ToolUtils.buildTree(list, "sortId", "sortPid", "childList");
    }

    /**
     * @Description 商品列表
     * @Date 2024/8/29 22:08
     * @Author YWX
     * @Param [iPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map>
     **/
    public IPage<Map> listGoods(Page<TGoodsExample> iPage, GoodsEntity entity) {
        String name = entity.getName();
        if (ToolUtils.isNotEmpty(name)) {//更新热词热度
            THotword hotword = tHotwordMapper.selectByName(name);
            if (hotword != null) {//存在热词，更新热度
                hotword.setPopularity(hotword.getPopularity() + 1);
                tHotwordMapper.updateById(hotword);
            } else {//不存在热词，新增热词
                hotword = new THotword();
                hotword.setHotword(name);
                hotword.setPopularity(1);
                tHotwordMapper.insert(hotword);
            }
        }
        return tGoodsExampleMapper.listGoods(iPage, entity);
    }

    /**
     * @Description 根据商品id获取商品列表
     * @Date 2024/9/28 20:40
     * @Author YWX
     * @Param [entity]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listGoodsByIds(GoodsEntity entity) {
        return tGoodsExampleMapper.listGoodsByIds(entity);
    }

    /**
     * @Description 客户浏览记录推荐商品列表
     * @Date 2024/9/1 17:44
     * @Author YWX
     * @Param [queryPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map < java.lang.String, java.lang.Object>>
     **/
    public IPage<Map<String, Object>> listRecommendedGoods(Page<TOrder> queryPage, OrderEntity entity) {
        entity.setCustomerid(serviceUtil.getCustomerId());
        return tCustomerGoodsRecordMapper.listGoods(queryPage, entity);
    }


    /**
     * @Description 商品详情
     * @Date 2024/9/1 11:33
     * @Author YWX
     * @Param [id]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> detailGoods(Integer id) {
        Map<String, Object> goods = tGoodsMapper.customerFindById(id);
        goods.put("logistics", goodsLogisticsMapper.findByGoodsId(id));
        Integer customerId = serviceUtil.getCustomerIdNoCheck();
        if (ToolUtils.isTrueInteger(customerId)) {
            autoCoupon(id, customerId);
        }
        return goods;
    }

    /**
     * @Description 商品规格列表
     * @Date 2024/9/1 14:10
     * @Author YWX
     * @Param [id]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> goodsSpecs(Integer id) {
        Map<String, Object> goods = new HashMap<>();
        goods.put("rents", goodsRentMapper.listByGoodsId(id));//租赁方案
        goods.put("attributes", goodsAttributeMapper.listByGoodsId(id));//商品属性
        goods.put("specs", goodsSpecsMapper.listByGoodsId(id));//销售规格
        return goods;
    }

    /**
     * @Description 自动领券
     * @Date 2024/9/1 15:10
     * @Author YWX
     * @Param [id]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void autoCoupon(Integer id) {
        Integer customerId = serviceUtil.getCustomerId();
        autoCoupon(id, customerId);
    }

    //自动领券
    @Async("asyncPoolTaskExecutor")
    public void autoCoupon(Integer id, Integer customerId) {
        List<Map> coupons = tCustomerCouponMapper.listGoodsCoupon(customerId, id, "autoCoupon");//客户可领商品券列表
        if (ToolUtils.isListNotEmpty(coupons)) {
            List<TCustomerCoupon> customerCoupons = new ArrayList<>();
            for (Map coupon : coupons) {
                if (!coupon.get("availableNum").equals(0)) {//已领取过未使用的优惠券不再领取
                    continue;
                }
                TCustomerCoupon customerCoupon = new TCustomerCoupon();
                customerCoupon.setCustomerid(customerId);
                customerCoupon.setCouponid(ToolUtils.objToInteger(coupon.get("couponid")));
                customerCoupon.setCreateid(customerId);
                customerCoupon.setCreatetime(LocalDateTime.now());
                LocalDateTime begin;
                LocalDateTime end;
                if (coupon.get("limitType").equals(1)) {//相对期限
                    begin = LocalDateTime.now();
                    end = begin.plusDays(ToolUtils.objToInteger(coupon.get("limitDay")));
                } else {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    begin = LocalDateTime.parse(ToolUtils.objToString(coupon.get("useTimeBegin")).replace("T", " "), formatter);
                    end = LocalDateTime.parse(ToolUtils.objToString(coupon.get("useTimeEnd")).replace("T", " "), formatter);
                }
                customerCoupon.setBeginDate(begin);
                customerCoupon.setEndDate(end);
                customerCoupons.add(customerCoupon);
            }
            if (ToolUtils.isListNotEmpty(customerCoupons)) {
                tCustomerCouponMapper.insertBatchSomeColumn(customerCoupons);
                String couponids = customerCoupons.stream().map(m -> ToolUtils.objToString(m.getCouponid())).reduce((a, b) -> a + "," + b).orElse("");
                tCouponMapper.updateUseNum(couponids);//更新优惠券可用数量
            }
        }
    }

    /**
     * @Description 获取商品价格
     * @Date 2024/9/1 15:51
     * @Author YWX
     * @Param [entity]
     * @Return java.lang.Double
     **/
    public Double goodsPrice(GoodsSpecsEntity entity) {
        Integer day = entity.getDay();
        Integer gsid = entity.getGsid();
        Integer num = entity.getNum();
        checkGoodsSpecs(gsid, num);//校验商品规格是否存在、库存是否充足
        TGoodsSpecsRent closestRent = getGoodsSpecsRent(gsid, day, num);//获取商品规格的租金信息并计算日单价
        return closestRent.getRent();
    }

    //获取商品规格的租金信息并计算日单价、总租金
    private @NotNull TGoodsSpecsRent getGoodsSpecsRent(Integer gsid, Integer day, Integer num) {
        List<TGoodsSpecsRent> specsList = goodsSpecsRentMapper.listByGsid(gsid);//根据商品规格获取租金列表
        TGoodsSpecsRent closestRent = serviceUtil.findClosestRent(specsList, day);//获取最接近的租金
        Integer day1 = closestRent.getDay();
        Double rent = closestRent.getRent();
        Double totalRent;
        if (day.equals(day1)) {// 如果当前天数与基准天数相同，则总租金等于租金
            totalRent = rent;
        } else {// 否则，计算总租金为租金乘以天数除以基准天数的商，并处理余数
            Double rent2 = ToolUtils.divideAndCeil(rent, day1);//计算每天租金
            totalRent = ToolUtils.multiply(rent2, day);//计算总租金=每天租金*天数
        }
        if (num > 1) {
            totalRent = ToolUtils.multiply(totalRent, num);
        }
        double dayPrice = ToolUtils.divideAndCeil(totalRent, day);
        closestRent.setDayPrice(dayPrice);//日单价
        closestRent.setRent(totalRent);//总租金
        return closestRent;
    }

    //校验商品规格是否存在、库存是否充足
    private TGoodsRent checkGoodsSpecs(Integer gsid, Integer num) {
        TGoodsRent goodsRent = goodsRentMapper.findByGsId(gsid);
        if (goodsRent == null) {
            throw new ServiceException("商品不存在！");
        } else if (goodsRent.getOutStock().equals(1) || goodsRent.getStock() < num) {
            throw new ServiceException("商品库存不足！");
        }
        return goodsRent;
    }

    /**
     * @Description 确认订单
     * @Date 2024/9/1 16:01
     * @Author YWX
     * @Param [entity]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> confirmOrder(GoodsSpecsEntity entity) {
        Integer customerId = serviceUtil.getCustomerIdNoCheck();
        TGoodsSpecs specs = goodsSpecsMapper.selectById(entity.getGsid());
        Integer num = entity.getNum();//购买数量
        if (specs == null) {
            throw new RuntimeException("商品不存在");
        } else if (specs.getOutStock().equals(1) || specs.getStock() < num) {
            throw new ServiceException("商品库存不足！");
        }
        Integer day = entity.getDay();
        Integer periods = serviceUtil.calculateLeasePeriods(day);//计算租期
        Double price = goodsPrice(entity);//计算价格
        Double deposit = specs.getDeposit();//押金
        Double depositPrice = entity.getDepositPrice();
        if (depositPrice != null) {
            deposit = depositPrice;
        }
        Integer goodsId = specs.getGoodsId();
        Integer couponid = entity.getCouponid();
        Double rentFirst;//首期租金
        Double rentLeft = 0.0;//剩余租期租金
        if (periods.equals(1)) {//如果租期为1，则首期租金为优惠后租金
            rentFirst = price;//首期租金
        } else {
            rentLeft = ToolUtils.divideAndCeilDown(price, periods);//剩余租期每期租金
            rentFirst = ToolUtils.subtract(price, ToolUtils.multiply(rentLeft, periods - 1));//首期租金=总租金-剩余租期租金*（租期-1）
        }
        Double goodsPrice = specs.getBuyPrice();
        double buyPrice = ToolUtils.multiply(goodsPrice, num);
        TCoupon coupon = getUseCoupon(couponid, customerId, goodsId, price, rentFirst, rentLeft, buyPrice, goodsPrice, periods, day);////获取可用优惠券
        Double shippingFee = 0.0;//运费
        Map<String, Object> logistics = goodsLogisticsMapper.findByGoodsId(goodsId);//获取物流信息
        if (logistics == null) {
            throw new ServiceException("物流信息不存在！");
        } else {
            Object outType = logistics.get("outType");
            Object inDay = logistics.get("inDay");//寄回运费或包邮天数
            if (outType.equals(2)) {//自付(租户自付邮费)
                shippingFee = (Double) logistics.get("expressFee");
            } else if (outType.equals(3) || (outType.equals(2) && ToolUtils.objToInteger(inDay).compareTo(day) < 0)) {//统一运费、或是下单不满天数
                shippingFee = (Double) logistics.get("shippingFee");
            }
        }
        Double couponPrice = 0.0;//优惠价钱
        Double rentAfterCoupon = price;//优惠后租金,默认为总租金
        Double rentFirstAfterCoupon = rentFirst;//优惠后首期租金
        double rentLeftAfterCoupon = rentLeft;//优惠后剩余租期租金
        Integer periodLeft = periods - 1;
        String voucherCode = "";
        if (coupon != null) {
            voucherCode = coupon.getVoucherCode();
            Double limitMoney = coupon.getLimitMoney();
            Integer couponType = coupon.getCouponType();//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
            Integer category = coupon.getCategory();//优惠券品类（1抵扣券2折扣券3特价券）
            Double useMoney = coupon.getMoney();
            Integer useCondition = coupon.getUseCondition();//使用条件（1签约价值2总租金3月租金）
            boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
            boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
            if (couponType.equals(1)) {//使用首期优惠券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(rentFirst, ToolUtils.divideAndCeil(useMoney, 10));
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(rentFirst, useMoney);
                } else {
                    couponPrice = useMoney;
                }
                rentFirstAfterCoupon = ToolUtils.subtract(rentFirst, couponPrice);//优惠后首期租金
                rentAfterCoupon = ToolUtils.subtract(price, couponPrice);
            } else if (couponType.equals(2)) {//使用其它期优惠券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(ToolUtils.multiply(rentLeft, ToolUtils.divideAndCeil(useMoney, 10)), periods - 1);
                    rentLeftAfterCoupon = ToolUtils.subtract(rentLeft, ToolUtils.divideAndCeil(useMoney, 10));//优惠后剩余租期租金
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(rentLeft, useMoney);
                    rentLeftAfterCoupon = useMoney;
                } else {
                    couponPrice = ToolUtils.multiply(useMoney, periods - 1);
                    rentLeftAfterCoupon = ToolUtils.subtract(rentLeft, useMoney);//优惠后剩余租期租金
                }
                rentAfterCoupon = ToolUtils.subtract(price, couponPrice);
            } else if (couponType.equals(3)) {//总租金券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(price, ToolUtils.divideAndCeil(useMoney, 10));
                    couponPrice = serviceUtil.getCouponPrice(coupon, couponPrice);
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(price, useMoney);
                } else {
                    couponPrice = useMoney;
                }
                if (periods.equals(1)) {//如果租期为1，则首期租金为优惠后租金
                    rentFirstAfterCoupon = ToolUtils.subtract(rentFirst, couponPrice);//优惠后首期租金
                } else {
                    rentAfterCoupon = ToolUtils.subtract(price, couponPrice);
                    rentLeftAfterCoupon = ToolUtils.divideAndCeilDown(rentAfterCoupon, periods);//剩余租期每期租金
                    rentFirstAfterCoupon = ToolUtils.subtract(rentAfterCoupon, ToolUtils.multiply(rentLeftAfterCoupon, periods - 1));//首期租金=总租金-剩余租期租金*（租期-1）
                }
            }
            couponid = coupon.getCouponid();
        } else {
            couponid = null;
        }
        Map<String, Object> result = new HashMap<>();
        result.put("voucherCode", voucherCode);//券码
        String format = "yyyy.MM.dd";
        result.put("planBegin", ToolUtils.getDateAfterDays(3, format));//预计起租日
        result.put("planEnd", ToolUtils.getDateAfterDays(day + 3, format));//预计归还日
        result.put("couponPrice", couponPrice);//优惠价钱
        result.put("shippingFee", shippingFee);//运费
        result.put("logistics", logistics);//配送信息
        result.put("deposit", deposit);//押金
        result.put("couponid", couponid);//优惠券ID
        result.put("rent", price);//总租金
        result.put("rentAfterCoupon", rentAfterCoupon);//优惠后租金
        result.put("rentFirst", rentFirst);//首期租金
        result.put("rentFirstAfterCoupon", rentFirstAfterCoupon);//优惠后首期租金
        result.put("specs", specs);//商品规格
        result.put("periods", periods);//租期
        result.put("periodLeft", periodLeft);//剩余租期
        result.put("rentLeft", rentLeft);//剩余租期租金
        result.put("rentLeftAfterCoupon", rentLeftAfterCoupon);//优惠后剩余租期租金
        result.put("buyPrice", buyPrice);
        result.put("buyPriceAfterStore", buyPrice);
        result.put("buyPriceEndDate", serviceUtil.getBuyPrice(buyPrice, rentAfterCoupon));
        result.put("day", day);
        Map<String, Object> set = platformSetMapper.getDetail();
        result.put("settlementRatio", set.get("settlementRatio"));
        result.put("renewalRate", set.get("renewalRate"));
        return result;
    }

    //获取可用优惠券
    private TCoupon getUseCoupon(Integer couponid, Integer customerId, Integer goodsId, Double price, Double
            rentFirst, Double rentLeft, Double buyPrice, Double goodsPrice, Integer periods, Integer day) {
        TCoupon coupon = null;
        if (!ToolUtils.isTrueInteger(customerId)) {
            return coupon;
        }
        if (ToolUtils.isTrueInteger(couponid)) {//用户选择了优惠券
            coupon = tCouponMapper.getUseCouponByCouponIdAndCustomerId(couponid, customerId);
            coupon = serviceUtil.checkCouponDay(day, coupon);
        } else {//用户未选择优惠券
            Double money = 0.0;//最高金额
            List<TCoupon> coupons = tCustomerCouponMapper.listCustomerCoupon(customerId, goodsId, 1);//客户已领商品券列表
            if (ToolUtils.isListNotEmpty(coupons)) {
                for (TCoupon tCoupon : coupons) {
                    if (serviceUtil.checkCouponDay(day, tCoupon) == null) {
                        continue;
                    }
                    Double limitMoney = tCoupon.getLimitMoney();
                    Integer couponType = tCoupon.getCouponType();//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
                    Integer category = tCoupon.getCategory();//优惠券品类（1抵扣券2折扣券3特价券）
                    Double useMoney = tCoupon.getMoney();
                    Integer useCondition = tCoupon.getUseCondition();//使用条件（1签约价值2总租金3月租金）
                    boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
                    boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
                    boolean qyj = useCondition.equals(1) && limitMoney.compareTo(goodsPrice) <= 0;//签约价
                    boolean zzj = useCondition.equals(2) && limitMoney.compareTo(price) <= 0;//总租金
                    Integer belongType = tCoupon.getBelongType();
                    Double ceilingAmount = tCoupon.getCeilingAmount();
                    boolean isCeiling = belongType.equals(2) && ceilingAmount != null;
                    if (couponType.equals(1) && (qyj || zzj || (useCondition.equals(3) && sq)) && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(rentFirst, ToolUtils.divideAndCeil(useMoney, 10));
                            if (isCeiling && money.compareTo(ceilingAmount) > 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = useMoney;
                        }
                        coupon = tCoupon;
                    } else if (couponType.equals(2) && (qyj || zzj || (useCondition.equals(3) && qtq)) && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(ToolUtils.multiply(rentLeft, ToolUtils.divideAndCeil(useMoney, 10)), periods - 1);
                            if (isCeiling && money.compareTo(ceilingAmount) < 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = ToolUtils.multiply(useMoney, periods - 1);
                        }
                        coupon = tCoupon;
                    } else if (couponType.equals(3) && useCondition.equals(2) && price.compareTo(limitMoney) >= 0 && limitMoney.compareTo(money) > 0) {//使用满减券，且满足使用条件
                        if (category.equals(2)) {
                            money = ToolUtils.multiply(price, ToolUtils.divideAndCeil(useMoney, 10));
                            if (isCeiling && money.compareTo(ceilingAmount) > 0) {
                                money = ceilingAmount;
                            }
                        } else {
                            money = useMoney;
                        }
                        coupon = tCoupon;
                    }
                }
            }
        }
        return coupon;
    }

    /**
     * @Description 获取用户是否认证
     * @Date 2024/9/1 22:26
     * @Author YWX
     * @Param []
     * @Return int
     **/
    public int getCustomerAuth() {
        Integer customerId = serviceUtil.getCustomerId();
        return serviceUtil.getCustomerAuth(customerId);
    }

    /**
     * @Description 上传认证附件
     * @Date 2024/9/2 0:29
     * @Author YWX
     * @Param [auth]
     * @Return cn.psvmc.cxzapi.response.Result
     **/
    public Result uploadAuth(MultipartFile file) {
        TCustomerAuth auth = new TCustomerAuth();
        Integer type = 0;
        String result;
        try {
            result = RecognizeIdcardUtil.recognizeIdCard(file);
        } catch (Exception e) {
            throw new ServiceException("实名认证失败！");
        }
        Map<String, Object> map = JSON.parseObject(result, Map.class);
        Warning warning = JSON.parseObject(ToolUtils.objToString(map.get("warning")), Warning.class);
        if (warning != null && warning.getTamperScore().compareTo(60F) > 0) {
            throw new ServiceException("实名认证失败！");
        }

        Map<String, Object> body = JSON.parseObject(ToolUtils.objToString(map.get("body")), Map.class);
        if (body != null) {
            Map<String, Object> data1 = JSON.parseObject(ToolUtils.objToString(body.get("data")), Map.class);
            if (data1 != null) {
                Map<String, Object> data2 = JSON.parseObject(ToolUtils.objToString(data1.get("data")), Map.class);
                if (data2 != null) {
                    Map<String, Object> face = JSON.parseObject(ToolUtils.objToString(data2.get("face")), Map.class);
                    if (face != null) {
                        Face data3 = JSON.parseObject(ToolUtils.objToString(face.get("data")), Face.class);
                        auth.setName(data3.getName());
                        auth.setSex(data3.getSex());
                        auth.setEthnicity(data3.getEthnicity());
                        auth.setBirthDate(data3.getBirthDate());
                        auth.setAddress(data3.getAddress());
                        auth.setIdNumber(data3.getIdNumber());
                        type = 1;
                    }
                    Map<String, Object> back = JSON.parseObject(ToolUtils.objToString(data2.get("back")), Map.class);
                    if (back != null) {
                        Back data3 = JSON.parseObject(ToolUtils.objToString(back.get("data")), Back.class);
                        auth.setIssueAuthority(data3.getIssueAuthority());
                        auth.setValidPeriod(data3.getValidPeriod());
                        type = 2;
                    }
                }
            }
        }

        String filepath = OssService.uploadFile(file, "admin_imgs/idcard");
        if (type.equals(0)) {
            throw new ServiceException("实名认证失败！");
        } else if (type.equals(1)) {
            auth.setFront(filepath);
        } else {
            auth.setBack(filepath);
        }
        auth.setType(type);
        return ResultGenerator.genSuccessResult("保存成功！", auth);
    }

    /**
     * @Description 用户可领取优惠券列表
     * @Date 2024/9/1 23:00
     * @Author YWX
     * @Param [id]
     * @Return java.util.List<cn.psvmc.cxzapi.model.store.TCoupon>
     **/
    public List<Map> listGoodsCoupon(Integer id) {
        Integer customerId = serviceUtil.getCustomerIdNoCheck();
        if (ToolUtils.isTrueInteger(customerId)) {
            return tCustomerCouponMapper.listGoodsCoupon(customerId, id, "listGoodsCoupon");
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * @Description 工单类型选择列表
     * @Date 2024/9/2 8:19
     * @Author YWX
     * @Param []
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listTicketType() {
        return tTicketTypeMapper.listForSel();
    }

    /**
     * @Description 工单原因选择列表
     * @Date 2024/9/2 8:21
     * @Author YWX
     * @Param [typeId]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listTicketCause(Integer typeId) {
        return tTicketCauseMapper.listByTypeIdForSel(typeId);
    }

    /**
     * @Description 添加工单
     * @Date 2024/9/2 8:24
     * @Author YWX
     * @Param [tTicket]
     * @Return int
     **/
    public int addTicket(TTicket tTicket) {
        TCustomer customer = serviceUtil.getCustomer();
        tTicket.setPhone(customer.getPhone());
        tTicket.setCustomerid(customer.getCustomerid());
        return tTicketMapper.insert(tTicket);
    }

    /**
     * @Description 工单回复
     * @Date 2024/9/2 8:29
     * @Author YWX
     * @Param [tTicketReplies]
     * @Return int
     **/
    public int addTicketReplies(TTicketReplies tTicketReplies) {
        serviceUtil.checkTicket(tTicketMapper.selectById(tTicketReplies.getTicketId()));//校验工单是否存在且未关闭
        tTicketReplies.setUsertype(2);
        return tTicketRepliesMapper.insert(tTicketReplies);
    }


    /**
     * @Description 工单回复详情
     * @Date 2024/9/2 8:31
     * @Author YWX
     * @Param [ticketId]
     * @Return java.util.Map
     **/
    public Map detailTicketReplies(Integer ticketId) {
        return tTicketRepliesMapper.findByTicketId(ticketId);
    }

    //校验身份证号是否不满18周岁
    public static boolean checkAgeFromIDCard(String idCard) {
        if (ToolUtils.isEmpty(idCard)) {
            return false;
        } else if (idCard.length() != 18) {
            return false;
        }

        // 提取出生日期
        String birthDateStr = idCard.substring(6, 14); // 格式为YYYYMMDD
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date birthDate;
        try {
            birthDate = sdf.parse(birthDateStr);
        } catch (ParseException e) {
            throw new RuntimeException("出生日期格式错误");
        }

        // 获取当前日期
        Date currentDate = new Date();

        // 计算年龄
        Integer age = currentDate.getYear() - birthDate.getYear();
        if (currentDate.getMonth() < birthDate.getMonth() ||
                (currentDate.getMonth() == birthDate.getMonth() && currentDate.getDate() < birthDate.getDate())) {
            age--;
        }

        return age.compareTo(18) < 0;
    }

    /**
     * @Description 下单
     * @Date 2024/9/3 8:47
     * @Author YWX
     * @Param [entity]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> addOrder(GoodsSpecsEntity entity) {
        Integer customerId = serviceUtil.getCustomerId();
        TCustomer tCustomer = serviceUtil.getAuthByCustomerId(customerId);//设置订单风控报告
        if (tCustomer != null && TCustomerGoodsService.checkAgeFromIDCard(tCustomer.getIdNumber())) {
            throw new ServiceException("未满18周岁禁止下单！");
        }
        //订单详情
        Map<String, Object> order = confirmOrder(entity);
        //检查商品是否已经下架
        TGoodsSpecs specs = (TGoodsSpecs) order.get("specs");
        TGoods tGoods = goodsMapper.selectById(specs.getGoodsId());
        if (tGoods == null || !tGoods.getGoodsStatus().equals(1)) {
            throw new ServiceException("商品已下架！");
        }
        // 创建订单信息
        TOrder tOrder = new TOrder();
        tOrder.setAddType(entity.getAddType()); //区分小程序下单或者快捷下单
        tOrder.setScene(entity.getScene()); //设置下单场景信息

        //设置账单信息
        List<TOrderBill> bills = new ArrayList<>();
        setOrder(tOrder, bills, entity, tGoods, order);

        tOrder.setCustomerid(customerId);

        Map<String, String> store = storeMapper.getStoreNameAndAddress(tOrder.getStoreid());
        tOrder.setIsWhite(tGoods.getIsWhite());
        tOrderMapper.insert(tOrder);

        //创建支付宝订单
        AlipayOpenMiniOrderCreateResponse response = AlipayCreate.alipayOpenMiniOrderCreate(tOrder, tCustomer, bills, tGoods, specs.getName(), store);
        tOrder.setTradeComponentOrderId(response.getOrderId());
        order.put("tradeComponentOrderId", tOrder.getTradeComponentOrderId());

        //线上资金授权冻结
        AlipayFundAuthOrderAppFreezeResponse freezeResponse = AlipayCreate.alipayFundAuthOrderAppFreeze(tOrder, tGoods);
        tOrder.setAuthNo(freezeResponse.getAuthNo());
        String orderStr = freezeResponse.getBody();
        order.put("orderStr", orderStr);
        tOrder.setOrderStr(orderStr);

        //租赁智能风险咨询（智安盾基础版）
        Map<String, String> riskMap = AlipayCreate.alipayCommerceRentRiskConsult(tCustomer.getOpenid(), tOrder.getOrderCode());
        if (riskMap.get("riskLevel") != null) {
            tOrder.setRiskLevel(riskMap.get("riskLevel"));
        }
        if (riskMap.get("riskScore") != null) {
            tOrder.setRiskScore(riskMap.get("riskScore"));
        }
        tOrderMapper.updateTradeInfoByOrderId(tOrder);//更新订单交易信息

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        RequestContextHolder.setRequestAttributes(requestAttributes, true);//设置子线程共享
        serviceUtil.saveOrderContract(tOrder, bills, tGoods.getName(), specs.getName(), tCustomer, 1, requestAttributes);

        Integer orderId = tOrder.getOrderId();
        for (TOrderBill bill : bills) {
            bill.setOrderId(orderId);
            tOrderBillMapper.insert(bill);
        }

        Integer stock = specs.getStock();
        int outStock = 0;
        if (stock.equals(entity.getNum())) {//购买数量等于库存，标记缺货
            outStock = 1;
        }
        specs.setOutStock(outStock);
        specs.setStock(entity.getNum());
        goodsSpecsMapper.uodateStock(specs);//更新库存

        Integer couponid = ToolUtils.objToInteger(order.get("couponid"));
        String voucherCode = ToolUtils.objToString(order.get("voucherCode"));
        serviceUtil.useCoupon(couponid, voucherCode, orderId, customerId, tOrder.getRentAfterCoupon());

        order.put("orderId", orderId);
        order.put("orderCode", tOrder.getOrderCode());
        order.put("customerAuth", getCustomerAuth());
        order.put("isWhite", tOrder.getIsWhite());
        order.put("createtime", tOrder.getCreatetime());
        return order;
    }


    //设置下单信息
    public void setOrder(TOrder tOrder, List<TOrderBill> bills, GoodsSpecsEntity entity, TGoods tGoods, Map<String, Object> order) {
        Integer sourceType = entity.getSourceType();
        if (ToolUtils.isTrueInteger(sourceType)) {
            tOrder.setSourceType(sourceType);  //订单来源
        }
        tOrder.setSourceId(entity.getSourceId()); //创建支付宝业务订单时传入
        tOrder.setSceneId(entity.getSceneId());  //场景编号支付宝订单需要
        Integer storeid = tGoods.getStoreid();
        tOrder.setOrderCode(CodeUtil.generateOrderCode());
        tOrder.setUsername(entity.getUsername());
        tOrder.setUserphone(entity.getUserphone());
        tOrder.setUserAddress(entity.getUserAddress());
        tOrder.setCustomerComm(entity.getCustomerComm());
        tOrder.setOrderStatus(0);
        tOrder.setGoodsId(tGoods.getGoodsId());
        tOrder.setStoreid(storeid);
        tOrder.setGsid(entity.getGsid());
        tOrder.setOrderType(1);
        Integer periods = ToolUtils.objToInteger(order.get("periods"));
        tOrder.setLeasePeriod(periods);
        Integer day = ToolUtils.objToInteger(order.get("day"));
        tOrder.setDay(day);
        LocalDateTime planBegin;
        String rentStartTime = entity.getRentStartTime();
        if (ToolUtils.isNotEmpty(rentStartTime)) {
            planBegin = ToolUtils.strToLocalDateTime(rentStartTime);
        } else {
            planBegin = LocalDate.now().plusDays(3).atTime(00, 00, 00);
        }
        tOrder.setPlanBegin(planBegin);
        LocalDateTime planEnd = planBegin.plusDays(day).minusSeconds(1);
        tOrder.setPlanEnd(planEnd);
        tOrder.setRealBegin(planBegin);
        tOrder.setRealEnd(planEnd);
        tOrder.setDeposit(ToolUtils.objToDouble(order.get("deposit")));
        tOrder.setRent(ToolUtils.objToDouble(order.get("rent")));
        tOrder.setRentAfterCoupon(ToolUtils.objToDouble(order.get("rentAfterCoupon")));
        tOrder.setNum(entity.getNum());
        tOrder.setShippingFee(ToolUtils.objToDouble(order.get("shippingFee")));
        tOrder.setBuyPrice(ToolUtils.objToDouble(order.get("buyPrice")));
        tOrder.setBuyPriceAfterStore(ToolUtils.objToDouble(order.get("buyPriceAfterStore")));
        Double settlementRatio = ToolUtils.objToDouble(order.get("settlementRatio"));
        tOrder.setSettlementRatio(settlementRatio);
        tOrder.setRenewalRate(ToolUtils.objToDouble(order.get("renewalRate")));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        TOrderBill bill = new TOrderBill();
        bill.setTransactionId(CodeUtil.generateBillSequence());
        Integer orderId = tOrder.getOrderId();
        bill.setOrderId(orderId);
        bill.setPeriod(1);
        bill.setOldPeriod(1);
        bill.setBeginTime(planBegin);
        bill.setEndTime(planBegin.plusDays(30).minusSeconds(1));
        bill.setPlanDate(planBegin.minusDays(1).format(formatter));
        bill.setBillAmount(ToolUtils.objToDouble(order.get("rentFirst")));
        bill.setOldAmount(bill.getBillAmount());
        bill.setDepositPay(0.0);
        bill.setPayAmount(ToolUtils.objToDouble(order.get("rentFirstAfterCoupon")));
        bill.setBillStatus(0);
        double storePrice1 = ToolUtils.multiply(bill.getPayAmount(), ToolUtils.divideAndCeil(settlementRatio, 100));
        storePrice1 = ToolUtils.formatDouble2(storePrice1);//商家收到的钱
        double platPrice1 = ToolUtils.subtract(bill.getPayAmount(), storePrice1);//平台扣除的钱
        bill.setStoreAmount(storePrice1);
        bill.setPlatformAmount(platPrice1);
        bill.setStoreid(storeid);
        bill.setInstallmentNo(bill.getPeriod());
        bills.add(bill);

        if (periods.compareTo(1) >= 1) {
            Double rentLeft = ToolUtils.objToDouble(order.get("rentLeft"));
            Double rentLeftAfterCoupon = ToolUtils.objToDouble(order.get("rentLeftAfterCoupon"));
            double storePrice = ToolUtils.multiply(rentLeftAfterCoupon, ToolUtils.divideAndCeil(settlementRatio, 100));
            storePrice = ToolUtils.formatDouble2(storePrice);//商家收到的钱
            double platPrice = ToolUtils.subtract(rentLeftAfterCoupon, storePrice);//平台扣除的钱
            for (int i = 2; i <= periods; i++) {
                TOrderBill bill2 = new TOrderBill();
                bill2.setTransactionId(CodeUtil.generateBillSequence());
                bill2.setOrderId(orderId);
                bill2.setPeriod(i);
                bill2.setOldPeriod(i);
                planBegin = planBegin.plusDays(30);
                bill2.setBeginTime(planBegin);
                bill2.setEndTime(planBegin.plusDays(30).minusSeconds(1));
                bill2.setPlanDate(planBegin.minusDays(1).format(formatter));
                bill2.setBillAmount(rentLeft);
                bill2.setOldAmount(bill2.getBillAmount());
                bill2.setDepositPay(0.0);
                bill2.setPayAmount(rentLeftAfterCoupon);
                bill2.setBillStatus(0);
                bill2.setStoreAmount(storePrice);
                bill2.setPlatformAmount(platPrice);
                bill2.setStoreid(storeid);
                bill2.setInstallmentNo(bill2.getPeriod());
                bills.add(bill2);
            }
        }

        for (TOrderBill orderBill : bills) {
            orderBill.setStageNo(1L);
            orderBill.setInstallmentNo(orderBill.getPeriod());
        }
    }

    /**
     * @Description 热词列表
     * @Date 2024/9/3 22:13
     * @Author YWX
     * @Param [name]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listHotword(String name) {
        return tHotwordMapper.listForSel(name);
    }

    /**
     * @Description 商品规格优惠券列表
     * @Date 2024/9/4 8:42
     * @Author YWX
     * @Param [entity]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listSpecsCoupon(GoodsSpecsEntity entity) {
        Integer customerId = serviceUtil.getCustomerIdNoCheck();
        if (ToolUtils.isTrueInteger(customerId)) {
            entity.setCustomerid(customerId);
            List<Map> list = tCustomerCouponMapper.listSpecsCoupon(entity);
            if (ToolUtils.isListEmpty(list)) return list;
            Map<String, Object> order = confirmOrder(entity);
            Double price = ToolUtils.objToDouble(order.get("rent"));
            Double rentFirst = ToolUtils.objToDouble(order.get("rentFirst"));
            Double rentLeft = ToolUtils.objToDouble(order.get("rentLeft"));
            Double buyPrice = ToolUtils.objToDouble(order.get("buyPrice"));
            Double goodsPrice = ToolUtils.objToDouble(order.get("goodsPrice"));
            Integer periods = ToolUtils.objToInteger(order.get("periods"));
            List<Map> result = new ArrayList<>();
            for (Map coupon : list) {
                coupon = serviceUtil.checkCouponDayAndPrice(coupon, entity.getDay(), price, rentFirst, rentLeft, buyPrice, goodsPrice, periods);
                if (coupon != null) {
                    result.add(coupon);
                }
            }
            return result;
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * @Description 认证
     * @Date 2024/9/4 22:27
     * @Author YWX
     * @Param [auth]
     * @Return cn.psvmc.cxzapi.response.Result
     **/
    @Transactional(rollbackFor = Exception.class)
    public Result addAuth(TCustomerAuth auth) {
        Integer customerId = serviceUtil.getCustomerId();
        auth.setCustomerid(customerId);
        Map<String, Object> oldAuth = tCustomerAuthMapper.findByCustomerId(customerId);
        String idNumber = auth.getIdNumber();
        if (ToolUtils.isNotEmpty(idNumber)) {
            String name = auth.getName();
            String inIdNumber = auth.getInIdNumber();
            String inRealName = auth.getInRealName();
            if (ToolUtils.isEmpty(inIdNumber) && oldAuth != null) {
                inIdNumber = ToolUtils.objToString(oldAuth.get("inIdNumber"));
                inRealName = ToolUtils.objToString(oldAuth.get("inRealName"));
            }
            if (ToolUtils.isNotEmpty(inIdNumber) && (!inIdNumber.equals(idNumber) || !inRealName.equals(name))) {
                throw new ServiceException("上传的身份证信息与支付宝绑定的不一致！");
            }
        }
        if (oldAuth != null) {
            auth.setCaid(ToolUtils.objToInteger(oldAuth.get("caid")));
            tCustomerAuthMapper.updateById(auth);
        } else {
            tCustomerAuthMapper.insert(auth);
        }

        return ResultGenerator.genSuccessResult("认证成功！", auth);
    }

    /**
     * @Description 我的工单
     * @Date 2024/9/7 10:49
     * @Author YWX
     * @Param [queryPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map < java.lang.String, java.lang.Object>>
     **/
    public IPage<Map<String, Object>> listMyTicket(Page<TOrder> queryPage, SearchEntity entity) {
        entity.setCustomerid(serviceUtil.getCustomerId());
        return tTicketMapper.listMyTicket(queryPage, entity);
    }

    /**
     * @Description 获取商品规格价格
     * @Date 2024/9/25 8:58
     * @Author YWX
     * @Param [entity]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> goodsPrice2(GoodsSpecsEntity entity) {
        Map<String, Object> result = new HashMap<>();
        Integer day = entity.getDay();
        Integer gsid = entity.getGsid();
        Integer num = entity.getNum();
        Integer customerId = serviceUtil.getCustomerIdNoCheck();
        TGoodsRent goodsRent = checkGoodsSpecs(gsid, num);//校验商品规格是否存在、库存是否充足
        TGoodsSpecsRent specsRent = getGoodsSpecsRent(gsid, day, num);//获取商品规格的租金信息并计算日单价
        Integer goodsId = goodsRent.getGoodsId();
        Double price = specsRent.getRent();
        if (num.compareTo(1) > 0) {
            price = ToolUtils.multiply(price, num);
        }
        Integer couponid = entity.getCouponid();
        Double rentFirst;//首期租金
        Double rentLeft = 0.0;//剩余租期租金
        Integer periods = serviceUtil.calculateLeasePeriods(day);//计算租期
        if (periods.equals(1)) {//如果租期为1，则首期租金为优惠后租金
            rentFirst = price;//首期租金
        } else {
            rentLeft = ToolUtils.divideAndCeilDown(price, periods);//剩余租期每期租金
            rentFirst = ToolUtils.subtract(price, ToolUtils.multiply(rentLeft, periods - 1));//首期租金=总租金-剩余租期租金*（租期-1）
        }
        Double goodsPrice = goodsRent.getBuyPrice();
        double buyPrice = ToolUtils.multiply(goodsPrice, num);
        TCoupon coupon = getUseCoupon(couponid, customerId, goodsId, price, rentFirst, rentLeft, buyPrice, goodsPrice, periods, day);////获取可用优惠券
        Double dayPrice = specsRent.getDayPrice();
        Double couponPrice = 0.0;
        Double dayPriceAfterCoupon = dayPrice;
        if (coupon != null) {
            Double limitMoney = coupon.getLimitMoney();
            Integer couponType = coupon.getCouponType();//优惠券类型（1首期优惠券2其它期优惠券3总租金券）
            Integer category = coupon.getCategory();//优惠券品类（1抵扣券2折扣券3特价券）
            Double useMoney = coupon.getMoney();
            Integer useCondition = coupon.getUseCondition();//使用条件（1签约价值2总租金3月租金）
            boolean sq = rentFirst.compareTo(limitMoney) >= 0.0;//首期优惠券是否满足首期租金条件
            boolean qtq = rentLeft.compareTo(limitMoney) >= 0.0;//其他期优惠券是否满足首期租金条件
            if (couponType.equals(1)) {//使用首期优惠券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(rentFirst, ToolUtils.divideAndCeil(useMoney, 10));
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(rentFirst, useMoney);
                } else {
                    couponPrice = useMoney;
                }
            } else if (couponType.equals(2)) {//使用其它期优惠券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(ToolUtils.multiply(rentLeft, ToolUtils.divideAndCeil(useMoney, 10)), periods - 1);
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(rentLeft, useMoney);
                } else {
                    couponPrice = ToolUtils.multiply(useMoney, periods - 1);
                }
            } else if (couponType.equals(3)) {//总租金券
                if (category.equals(2)) {
                    couponPrice = ToolUtils.multiply(price, ToolUtils.divideAndCeil(useMoney, 10));
                    serviceUtil.getCouponPrice(coupon, couponPrice);
                } else if (category.equals(3)) {
                    couponPrice = ToolUtils.subtract(price, useMoney);
                } else {
                    couponPrice = useMoney;
                }
            }
            Double rentAfterCoupon = ToolUtils.subtract(price, couponPrice);//优惠后的租金
            dayPriceAfterCoupon = ToolUtils.divideAndCeil(rentAfterCoupon, day);//优惠后的日单价
            if (dayPriceAfterCoupon.compareTo(dayPrice) > 0) {//优惠后的日单价大于原日单价，则取原日单价
                dayPriceAfterCoupon = dayPrice;
            }
        }
        result.put("dayPrice", dayPrice);//原日单价
        result.put("dayPriceAfterCoupon", dayPriceAfterCoupon);//优惠后的日单价
        result.put("rentCoupon", couponPrice);//优惠金额
        Map<String, Object> result2 = new HashMap<>();
        result.put("buyPrice", buyPrice);//原始买断价
        result.put("buyPriceAfterStore", buyPrice);//申请买断要支付的买断价
        result.put("buyPriceEndDate", serviceUtil.getBuyPrice(buyPrice, goodsPrice(entity)));//到期买断价
        return result;
    }

    /**
     * @Description 快捷下单查询租金、分期计划、免押风控的信息
     * @Date 2025/1/14 23:51
     * @Author YWX
     * @Param [item]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> rentOrderInit(TOrderItem item) {
        GoodsSpecsEntity entity = new GoodsSpecsEntity();
        entity.setGsid(ToolUtils.objToInteger(item.getOutSkuId()));
        entity.setDay(item.getDuration());
        entity.setNum(item.getQuantity());
        Map<String, Object> map = confirmOrder(entity);
        Map<String, Object> rent = new LinkedHashMap<>();
        // 租金信息
        Map<String, Object> costInfo = new LinkedHashMap<>();
        costInfo.put("originalPrice", map.get("rent"));
        costInfo.put("discountedPrice", map.get("couponPrice"));
        costInfo.put("totalRent", map.get("rentAfterCoupon"));
        Object deposit = map.get("deposit");
        costInfo.put("deposit", deposit);

        // 分期计划
        String rentStartTime = item.getRentStartTime();
        LocalDateTime startTime = ToolUtils.strToLocalDateTime(rentStartTime);
        Map<String, Object> stagePayPlan = new LinkedHashMap<>();
        List<Map> stagePayPlanInfos = new ArrayList<>();
        Integer periods = ToolUtils.objToInteger(map.get("periods"));
        Map<String, Object> stagePayPlanInfo = new LinkedHashMap<>();
        stagePayPlanInfo.put("planPayNo", 1);
        stagePayPlanInfo.put("planPayTime", rentStartTime);
        stagePayPlanInfo.put("originalPrice", map.get("rentFirst"));
        stagePayPlanInfo.put("discountedPrice", ToolUtils.subtract(map.get("rentFirst"), map.get("rentFirstAfterCoupon")));
        stagePayPlanInfo.put("planPayPrice", map.get("rentFirstAfterCoupon"));
        stagePayPlanInfos.add(stagePayPlanInfo);
        if (periods.compareTo(1) > 0) {
            for (int i = 1; i < periods; i++) {
                stagePayPlanInfo = new LinkedHashMap<>();
                startTime = startTime.plusDays(30);
                stagePayPlanInfo.put("planPayNo", i + 1);
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                stagePayPlanInfo.put("planPayTime", startTime.format(formatter));
                stagePayPlanInfo.put("originalPrice", map.get("rentLeft"));
                stagePayPlanInfo.put("discountedPrice", ToolUtils.subtract(map.get("rentLeft"), map.get("rentLeftAfterCoupon")));
                stagePayPlanInfo.put("planPayPrice", map.get("rentLeftAfterCoupon"));
                stagePayPlanInfos.add(stagePayPlanInfo);
            }
        }
        stagePayPlan.put("stagePayPlanInfos", stagePayPlanInfos);
        costInfo.put("stagePayPlan", stagePayPlan);
        rent.put("costInfo", costInfo);

        //芝麻免押风控需要的参数
        Map<String, Object> advanceRiskCtrlParam = new LinkedHashMap<>();
        advanceRiskCtrlParam.put("serviceId", ConfigKey.serviceId);
        advanceRiskCtrlParam.put("categoryId", "RENT_COMPUTER");
        advanceRiskCtrlParam.put("maxDeductAmount", deposit);
        rent.put("advanceRiskCtrlParam", advanceRiskCtrlParam);
        return rent;
    }

    /**
     * @Description 快捷下单-创建业务订单
     * @Date 2025/1/15 22:09
     * @Author YWX
     * @Param [item]
     * @Return java.lang.Object
     **/
    public Object rentOrderSubmit(Map<String, Object> item) {
        //收货地址信息
        Map<String, String> addressInfo = (Map<String, String>) item.get("addressInfo");
        GoodsSpecsEntity entity = new GoodsSpecsEntity();
        entity.setAddType(2);
        String userAddress = ToolUtils.objToString(addressInfo.get("country")) + ToolUtils.objToString(addressInfo.get("prov"))
                + ToolUtils.objToString(addressInfo.get("city")) + ToolUtils.objToString(addressInfo.get("area")) + ToolUtils.objToString(addressInfo.get("address"));
        entity.setUserAddress(userAddress);
        entity.setUsername(addressInfo.get("fullname"));
        entity.setUserphone(addressInfo.get("mobilePhone"));

        //商品详细信息
        Map<String, Object> itemInfo = (Map<String, Object>) item.get("itemInfo");
        entity.setGsid(ToolUtils.objToInteger(itemInfo.get("outSkuId")));

        //订单信息
        Map<String, Object> orderInfo = (Map<String, Object>) item.get("orderInfo");
        entity.setCustomerComm(ToolUtils.objToString(orderInfo.get("orderMemo")));
        entity.setNum(ToolUtils.objToInteger(orderInfo.get("quantity")));

        //租金信息
        Map<String, Object> rentInfo = (Map<String, Object>) item.get("rentInfo");
        entity.setDepositPrice(ToolUtils.objToDouble(rentInfo.get("depositPrice")));
        entity.setRentStartTime(ToolUtils.objToString(rentInfo.get("rentStartTime")));
        entity.setRentEndTime(ToolUtils.objToString(rentInfo.get("rentEndTime")));
        entity.setDay(ToolUtils.objToInteger(rentInfo.get("duration")));

        entity.setSourceId(ToolUtils.objToString(item.get("sourceId")));
        entity.setSceneId(ToolUtils.objToString(item.get("sceneId")));
        entity.setSourceType(ToolUtils.objToInteger(item.get("sourceType")));
        entity.setScene(ToolUtils.objToString(item.get("scene")));
        Map<String, Object> result = new LinkedHashMap<>();
        Map<String, Object> map = addOrder(entity);
        result.put("tradeComponentOrderId", map.get("tradeComponentOrderId"));//交易组件订单号
        result.put("orderCode", map.get("orderCode"));//商户订单号，与创建交易组件订单的商户订单号out_order_id保持一致
        result.put("orderId", map.get("orderId"));//商户订单id
        return result;
    }
}
